﻿using System;
using System.Windows.Forms;
using System.IO;
using System.Globalization;

using Styx;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

namespace PPRecorder
{
    public partial class PPRForm : Form
    {
        #region PPRecorder Variables
        // button txt
        const string SetVendor = "Set vendor";
        const string UdVendor = "Update vendor";
        const string SetMailbox = "Set mailbox";
        const string UdMailbox = "Update mailbox";
        const string StartSpot = "Set begin of the run";
        const string EndSpot = "Set end of the run";
        const string AddSpot = "Add spot";
        const string DelLast = "Delete last";
        const string ExportLog = "Export log";
        const string SendLog = "Send log";
        int mobNumber = 0;

        // General
        private const string NO_LOCATION = "I couldn't find a location - please try again";
        // Vendors
        private const string NO_TARGET = "No target selected - please select a target and try again";
        private const string INVALID_TARGET = "No valid target select - please select a valid target and try again";
        private const string NOT_IN_RANGE = "Not in repair range of the selected target - please move closer and try again";     
        #endregion

        #region PPRecorder Initialze
        private LocalPlayer Me = StyxWoW.Me;

        public PPRForm()
        {
            InitializeComponent();
            generateVendor.Text = SetVendor;
            generateMailbox.Text = SetMailbox;
            startSpotbtn.Text = StartSpot;
            endSpotbtn.Text = EndSpot;
            generateSpot.Text = AddSpot;
            deleteLastSpot.Text = DelLast;
            exportLogbtn.Text = ExportLog;
            sendLogbtn.Text = SendLog;
        }

        private void PPRecorderForm_Load(object sender, EventArgs e)
        {
            profileCreatorGrp.Visible = false;  // hide generator
            generateMailbox.Enabled = false;    // we dont want the user to set a mailbox before setting a vendor
            startSpotbtn.Enabled = false;       // have to set a mailbox first
            endSpotbtn.Enabled = false;         // have to set a mailbox first
            generateSpot.Enabled = false;       // no reason to start recording spots, there's no valid start spot yet..
            deleteLastSpot.Enabled = false;     // no reason to enable this button if there's no generated spot yet
            saveProfile.Enabled = false;        // no reason to allow the user to save if there's no valid profile yet

            dataGridView1.DataSource = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format(@"Plugins/PPRecorder/Profiles/"))).GetFiles();
        }
        #endregion

        #region PPRecorder New Profile
        private void newProfile_Click(object sender, EventArgs e)
        {
            RLog("Creating a new profile..");
            RLog("Done!");

            profileCreatorGrp.Visible = true;   // user managed to set a name, show creator
            newProfile.Enabled = false;         // user is generating a new profile, no need to keep this clickable
        }
        #endregion

        #region PPRecorder Methods

        // getVendorCoords - Attempts to set the vendor

        private bool getVendorCoords()
        {
            ObjectManager.Update();
            if (Styx.StyxWoW.IsInWorld)
            {// check if there's an actual location
                if (Me.CurrentTarget != null) // check if we got a target
                {
                    if (Me.CurrentTarget.IsRepairMerchant == true) // check if our target is a repair merchant
                    {
                        if (Me.CurrentTarget.Distance <= 4.9) // check if we are in trade range of our target
                        {
                            Utilities.DhInstance.NPC = Me.CurrentTarget.Name;
                            Utilities.DhInstance.X = Me.Location.X;
                            Utilities.DhInstance.Y = Me.Location.Y;
                            Utilities.DhInstance.Z = Me.Location.Z;
                            X_V_label.Text = Utilities.DhInstance.X.ToString();
                            Y_V_label.Text = Utilities.DhInstance.Y.ToString();
                            Z_V_label.Text = Utilities.DhInstance.Z.ToString();
                            NPC_V_label.Text = Utilities.DhInstance.NPC;
                            Utilities.DhInstance.vendorX = Me.Location.X;
                            Utilities.DhInstance.vendorY = Me.Location.Y;
                            Utilities.DhInstance.vendorZ = Me.Location.Z;
                            if (Utilities.DhInstance.vendors.Count > 0)
                            {
                                var nSpot = "<Vendor Name=\"" + Me.CurrentTarget.Name + "\" Entry=\"" +
                                            Me.CurrentTarget.Entry + "\" Type=\"Repair\" X=\"" +
                                            Utilities.DhInstance.X.ToString(new CultureInfo("en-US")) + "\" Y=\"" +
                                            Utilities.DhInstance.Y.ToString(new CultureInfo("en-US")) + "\" Z=\"" +
                                            Utilities.DhInstance.Z.ToString(new CultureInfo("en-US")) + "\" />";
                                Utilities.DhInstance.vendors[0] = nSpot;
                                return true;
                            }
                            var fSpot = "<Vendor Name=\"" + Me.CurrentTarget.Name + "\" Entry=\"" +
                                        Me.CurrentTarget.Entry + "\" Type=\"Repair\" X=\"" +
                                        Utilities.DhInstance.X.ToString(new CultureInfo("en-US")) + "\" Y=\"" +
                                        Utilities.DhInstance.Y.ToString(new CultureInfo("en-US")) + "\" Z=\"" +
                                        Utilities.DhInstance.Z.ToString(new CultureInfo("en-US")) + "\" />";
                            Utilities.DhInstance.vendors.Add(fSpot);
                            return true;
                        }
                        RLog(NOT_IN_RANGE);
                        return false;
                    }
                    RLog(INVALID_TARGET);
                    return false;
                }
                RLog(NO_TARGET);
                return false;
            }
            RLog(NO_LOCATION);
            return false;
        }

        private bool getMBCoords()
        {
            if (Styx.StyxWoW.IsInWorld)
            {
                Utilities.DhInstance.X = Me.Location.X;
                Utilities.DhInstance.Y = Me.Location.Y;
                Utilities.DhInstance.Z = Me.Location.Z;
                Utilities.DhInstance.MB = Me.ZoneText.ToString();
                X_MB_label.Text = Utilities.DhInstance.X.ToString();
                Y_MB_label.Text = Utilities.DhInstance.Y.ToString();
                Z_MB_label.Text = Utilities.DhInstance.Z.ToString();
                ZONE_MB_label.Text = Utilities.DhInstance.MB;
                if (Utilities.DhInstance.mailboxes.Count > 0)
                    // check if there's a mailbox already, update current if there is
                {
                    var nSpot = "<Mailbox X=\"" + Utilities.DhInstance.X.ToString(new CultureInfo("en-US")) + "\" Y=\"" +
                                Utilities.DhInstance.Y.ToString(new CultureInfo("en-US")) + "\" Z=\"" + Utilities.DhInstance.Z.ToString(new CultureInfo("en-US")) +
                                "\" />";
                    Utilities.DhInstance.mailboxes[0] = nSpot;
                    return true;
                }
                var fSpot = "<Mailbox X=\"" + Utilities.DhInstance.X.ToString(new CultureInfo("en-US")) + "\" Y=\"" +
                            Utilities.DhInstance.Y.ToString(new CultureInfo("en-US")) + "\" Z=\"" + Utilities.DhInstance.Z.ToString(new CultureInfo("en-US")) + "\" />";
                Utilities.DhInstance.mailboxes.Add(fSpot);
                return true;
            }
            RLog(NO_LOCATION);
            return false;
        }

        private bool getSpotCoords()
        {
            ObjectManager.Update();
            if (Me.CurrentTarget != null)
            {
                if (Styx.StyxWoW.IsInWorld) // check if there's an actual location
                {
                    mobNumber++;
                    Utilities.DhInstance.X = Me.Location.X;
                    Utilities.DhInstance.Y = Me.Location.Y;
                    Utilities.DhInstance.Z = Me.Location.Z;
                    Utilities.DhInstance.MOB = Me.CurrentTarget.Name;
                    X_S_label.Text = Utilities.DhInstance.X.ToString();
                    Y_S_label.Text = Utilities.DhInstance.Y.ToString();
                    Z_S_label.Text = Utilities.DhInstance.Z.ToString();
                    MOB_S_label.Text = Utilities.DhInstance.MOB;
                    var fSpot = "<CustomBehavior File=\"NoCombatMoveTo\" X=\"" + Utilities.DhInstance.X.ToString(new CultureInfo("en-US")) + "\" Y=\"" + Utilities.DhInstance.Y.ToString(new CultureInfo("en-US")) + "\" Z=\"" + Utilities.DhInstance.Z.ToString(new CultureInfo("en-US")) + "\" />\t<!-- Mob Number: " + mobNumber.ToString() + " -->@<CustomBehavior File=\"RunMacro\" Macro=\"/target " + Utilities.DhInstance.MOB + "\" NumOfTimes=\"1\" WaitTime=\"100\" />";
                    Utilities.DhInstance.spots.Add(fSpot);
                    return true;
                }
                RLog(NO_LOCATION);
                return false;      
            }
            RLog(NO_TARGET);
            return false;
        }

        private bool setStartSpot()
        {
            if (Styx.StyxWoW.IsInWorld) // check if there's an actual location
            {
                Utilities.DhInstance.startX = Me.Location.X;
                Utilities.DhInstance.startY = Me.Location.Y;
                Utilities.DhInstance.startZ = Me.Location.Z;
                Utilities.DhInstance.MOB = "<no target>";
                X_S_label.Text = Utilities.DhInstance.startX.ToString();
                Y_S_label.Text = Utilities.DhInstance.startY.ToString();
                Z_S_label.Text = Utilities.DhInstance.startZ.ToString();
                MOB_S_label.Text = Utilities.DhInstance.MOB;
                return true;
            }
            RLog(NO_LOCATION);
            return false;
        }

        private bool setEndSpot()
        {
            if (Styx.StyxWoW.IsInWorld) // check if there's an actual location
            {
                Utilities.DhInstance.endX = Me.Location.X;
                Utilities.DhInstance.endY = Me.Location.Y;
                Utilities.DhInstance.endZ = Me.Location.Z;
                Utilities.DhInstance.MOB = "<no target>";
                X_S_label.Text = Utilities.DhInstance.endX.ToString();
                Y_S_label.Text = Utilities.DhInstance.endY.ToString();
                Z_S_label.Text = Utilities.DhInstance.endZ.ToString();
                MOB_S_label.Text = Utilities.DhInstance.MOB;
                return true;
            }
            RLog(NO_LOCATION);
            return false;
        }

        #endregion

        #region PPRecorder Logging
        // Writes to our custom log
        public void RLog(string msg)
        {
            recorderLog.Text += "[" + DateTime.Now.ToString("HH:mm:ss tt") + "] " + msg + Environment.NewLine;
            recorderLog.SelectionStart = recorderLog.Text.Length;
            recorderLog.ScrollToCaret();
        }

        // Writes a error to our custom log
        public void RLog_err(string msg, string err)
        {
            recorderLog.Text += "[" + DateTime.Now.ToString("HH:mm:ss tt") + "] " + msg + Environment.NewLine;
            recorderLog.SelectionStart = recorderLog.Text.Length;
            recorderLog.ScrollToCaret();
        }
        #endregion
  
        #region PPRecorder Buttons
        // Generate Vendor - Attempts to set/update the vendor
        private void generateVendor_Click(object sender, EventArgs e)
        {
            switch (generateVendor.Text)
            {
                case(SetVendor):
                    if (!getVendorCoords()) return;
                    generateMailbox.Enabled = true;     // hooray, user has set a repair npc
                    generateVendor.Text = UdVendor;
                    RLog("Succesfully added our vendor at X: " + Utilities.DhInstance.X.ToString() + " Y: " + Utilities.DhInstance.Y.ToString() + " Z: " + Utilities.DhInstance.Z.ToString() + ", the vendor's name is : " + Utilities.DhInstance.NPC);
                    break;
                case(UdVendor):
                    if (!getVendorCoords()) return;
                    RLog("Succesfully updated our vendor at X: " + Utilities.DhInstance.X.ToString() + " Y: " + Utilities.DhInstance.Y.ToString() + " Z: " + Utilities.DhInstance.Z.ToString() + ", the vendor's name is : " + Utilities.DhInstance.NPC);
                    break;
            }

        }

        // Generate Mailbox - Attempts to set/update the mailbox
        private void generateMailbox_Click(object sender, EventArgs e)
        {
            switch (generateMailbox.Text)
            {
                case(SetMailbox):
                    if (!getMBCoords()) return;
                    startSpotbtn.Enabled = true;        // hooray once again, the user managed to set a mailbox
                    endSpotbtn.Enabled = true;
                    generateMailbox.Text = UdMailbox;
                    RLog("Succesfully added our mailbox at X: " + Utilities.DhInstance.X.ToString() + " Y: " + Utilities.DhInstance.Y.ToString() + " Z: " + Utilities.DhInstance.Z.ToString() + ", the zone name is: " + Utilities.DhInstance.MB);
                    break;
                case(UdMailbox):
                    if (!getMBCoords()) return;
                    RLog("Succesfully updated our mailbox at X: " + Utilities.DhInstance.X.ToString() + " Y: " + Utilities.DhInstance.Y.ToString() + " Z: " + Utilities.DhInstance.Z.ToString() + ", the zone name is: " + Utilities.DhInstance.MB);       
                    break;
            }
        }

        // Generate Spot - Attempts to set a new spot
        private void generateSpot_Click(object sender, EventArgs e)
        {
            if (!getSpotCoords()) return;
            saveProfile.Enabled = true;
            deleteLastSpot.Enabled = true;
            RLog("Succesfully added a new spot at X: " + Utilities.DhInstance.X.ToString() + " Y: " + Utilities.DhInstance.Y.ToString() + " Z: " + Utilities.DhInstance.Z.ToString() + ", our selected mob was: " + Utilities.DhInstance.MOB);
        }

        // Delete Last Spot - Attempts to delete the last spot
        private void deleteLastSpot_Click(object sender, EventArgs e)
        {
            mobNumber--;
            int lastEntry = Utilities.DhInstance.spots.Count - 1;
            Utilities.DhInstance.spots.RemoveAt(lastEntry);
            RLog("Removed last added spot");
        }

        // Save Profile - Prompts the user the final save form
        private void saveProfile_Click(object sender, EventArgs e)
        {
            new SaveForm().Show();
        }

        // Start Spot - Attempts to set the starting spot
        private void startSpotbtn_Click(object sender, EventArgs e)
        {
            if (!setStartSpot()) return;
            generateSpot.Enabled = true;
            RLog("Starting spot is set at X: " + Utilities.DhInstance.startX.ToString() + " Y: " + Utilities.DhInstance.startY.ToString() + " Z: " + Utilities.DhInstance.startZ.ToString());
        }

        // End Spot - Attempts to set the ending spot
        private void endSpotbtn_Click(object sender, EventArgs e)
        {
            if (!setEndSpot()) return;
            RLog("Ending spot is set at X: " + Utilities.DhInstance.endX.ToString() + " Y: " + Utilities.DhInstance.endY.ToString() + " Z: " + Utilities.DhInstance.endZ.ToString());
        }

        // Export Log - nothing yet
        private void exportLogbtn_Click(object sender, EventArgs e)
        {
            
        }

        // Send Log - nothing yet
        private void sendLog_Click(object sender, EventArgs e)
        {
            //DialogResult dialogResult = MessageBox.Show("You are about to send your log to my server, no personal data will be send.", "Are you sure?", MessageBoxButtons.YesNo, MessageBoxIcon.Information); // notify the user what's going to happen
            //if (dialogResult == DialogResult.Yes)
            //{
            //    rLog("Sending log to server..");
            //    rLog("Succesful.");
            //}
            //else if (dialogResult == DialogResult.No)
            //{
            //
            //}
        }
        #endregion
    }
}
